"""配置数据模型"""

from pydantic import BaseModel, Field, field_validator, ConfigDict
from pathlib import Path
from typing import List, Dict, Any, Optional
from datetime import datetime


class LLMConfig(BaseModel):
    """大模型配置"""
    default_provider: str = Field(default="local", description="默认提供商")
    
    # 本地模型配置
    local_enabled: bool = Field(default=True, description="启用本地模型")
    local_model: str = Field(default="qwen2.5:7b", description="本地模型名称")
    local_endpoint: str = Field(default="http://localhost:11434", description="本地API端点")
    
    # OpenAI配置
    openai_enabled: bool = Field(default=False, description="启用OpenAI")
    openai_model: str = Field(default="gpt-4", description="OpenAI模型")
    openai_api_key: str = Field(default="", description="OpenAI API密钥")
    openai_base_url: str = Field(default="https://api.openai.com/v1", description="OpenAI基础URL")
    
    # Claude配置
    claude_enabled: bool = Field(default=False, description="启用Claude")
    claude_model: str = Field(default="claude-3-sonnet-20240229", description="Claude模型")
    claude_api_key: str = Field(default="", description="Claude API密钥")
    
    # 智谱AI配置
    zhipu_enabled: bool = Field(default=False, description="启用智谱AI")
    zhipu_model: str = Field(default="glm-4", description="智谱AI模型")
    zhipu_api_key: str = Field(default="", description="智谱AI API密钥")
    
    # 通用配置
    request_timeout: int = Field(default=30, description="请求超时时间(秒)")
    max_retries: int = Field(default=3, description="最大重试次数")
    cache_ttl: int = Field(default=3600, description="缓存TTL(秒)")
    
    @field_validator('default_provider')
    @classmethod
    def validate_provider(cls, v):
        """验证提供商名称"""
        valid_providers = ['local', 'openai', 'claude', 'zhipu']
        if v not in valid_providers:
            raise ValueError(f"提供商必须是: {valid_providers}")
        return v


class UserPreferences(BaseModel):
    """用户偏好配置"""
    # 命名偏好
    date_format: str = Field(default="YYYY年MM月", description="日期格式偏好")
    classification_priority: str = Field(default="content", description="分类优先级: content/time/type")
    auto_confirm: bool = Field(default=False, description="自动确认归档")
    create_date_folders: bool = Field(default=True, description="创建日期文件夹")
    
    # 自定义提示词
    custom_prompts: List[str] = Field(default_factory=list, description="自定义提示词")
    special_rules: Dict[str, str] = Field(default_factory=dict, description="特殊规则配置")
    
    # 路径习惯
    path_preferences: Dict[str, Any] = Field(
        default_factory=lambda: {
            "work_files": "按项目分组",
            "personal_files": "按年份+类型分组", 
            "photos": "按时间+事件分组"
        },
        description="路径偏好"
    )
    
    def add_custom_prompt(self, prompt: str) -> None:
        """添加自定义提示词"""
        if prompt not in self.custom_prompts:
            self.custom_prompts.append(prompt)
    
    def add_special_rule(self, keyword: str, rule: str) -> None:
        """添加特殊规则"""
        self.special_rules[keyword] = rule


class AppConfig(BaseModel):
    """应用配置"""
    # 应用基本信息
    app_name: str = Field(default="文件归纳所", description="应用名称")
    app_version: str = Field(default="1.0.0", description="应用版本")
    language: str = Field(default="zh_CN", description="界面语言")
    theme: str = Field(default="light", description="界面主题")
    
    # 数据库配置
    database_path: Path = Field(default=Path("~/.file_organizer/data.db"), description="数据库路径")
    backup_enabled: bool = Field(default=True, description="启用备份")
    backup_interval: int = Field(default=86400, description="备份间隔(秒)")
    
    # UI配置
    window_size: List[int] = Field(default=[1000, 700], description="窗口大小")
    min_window_size: List[int] = Field(default=[800, 600], description="最小窗口大小")
    auto_save_interval: int = Field(default=300, description="自动保存间隔(秒)")
    max_recent_workspaces: int = Field(default=10, description="最大最近工作空间数")
    
    # 文件操作配置
    backup_before_move: bool = Field(default=True, description="移动前备份")
    confirm_destructive_actions: bool = Field(default=True, description="确认破坏性操作")
    max_batch_size: int = Field(default=100, description="最大批量大小")
    progress_update_interval: int = Field(default=100, description="进度更新间隔(毫秒)")
    
    model_config = ConfigDict(
        json_encoders={
            Path: str,
            datetime: lambda v: v.isoformat()
        }
    )
    
    @field_validator('window_size', 'min_window_size')
    @classmethod
    def validate_window_size(cls, v):
        """验证窗口大小"""
        if len(v) != 2 or v[0] <= 0 or v[1] <= 0:
            raise ValueError("窗口大小必须是两个正整数")
        return v


class Config(BaseModel):
    """主配置类"""
    llm: LLMConfig = Field(default_factory=LLMConfig, description="大模型配置")
    user_preferences: UserPreferences = Field(default_factory=UserPreferences, description="用户偏好")
    app: AppConfig = Field(default_factory=AppConfig, description="应用配置")
    
    updated_at: datetime = Field(default_factory=datetime.now, description="更新时间")
    
    model_config = ConfigDict(
        json_encoders={
            Path: str,
            datetime: lambda v: v.isoformat()
        }
    )
    
    def update_timestamp(self) -> None:
        """更新时间戳"""
        self.updated_at = datetime.now()